package com.xing.acl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xing.acl.entity.Permission;
import com.xing.acl.entity.RolePermission;
import com.xing.acl.mapper.PermissionMapper;
import com.xing.acl.service.PermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xing.acl.service.RolePermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 权限 服务实现类
 * </p>
 *
 * @author xingfuao
 * @since 2022-04-19
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private RolePermissionService rolePermissionService;

    //获取全部菜单
    @Override
    public List<Permission> queryAllMenuGuli() {
        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        List<Permission> permissionList = baseMapper.selectList(wrapper);

        List<Permission> result = build(permissionList);

        return result;
    }

    //递归删除菜单
    @Override
    public void removeChildById(String id) {
        //1.创建list集合，用于封装所有删除菜单id的值
        List<String> idlist = new ArrayList<>();
        //2.向idlist集合设置删除菜单的id
        this.selectPermissionChildById(id,idlist);
        //把当前id封装到list里面
        idlist.add(id);
        baseMapper.deleteBatchIds(idlist);


    }

    //给角色分配权限
    @Override
    public void saveRolePermissionRealtionShipGuli(String roleId, String[] permissionIds) {
        //1先删除角色权限表的数据，之后再重新循环添加权限
        QueryWrapper<RolePermission> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id",roleId);
        rolePermissionService.remove(wrapper);

        List<RolePermission> rolePermissionList = new ArrayList<>();
        for (String permissionId : permissionIds) {
            if(StringUtils.isEmpty(permissionId)){
                continue;
            }
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissionList.add(rolePermission);
        }
        rolePermissionService.saveBatch(rolePermissionList);
    }

    //2.根据当前菜单id,查询菜单里面子菜单id，封装到list集合中
    private void selectPermissionChildById(String id, List<String> idlist) {
        //查询菜单里面子菜单id
        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.eq("pid",id);
        wrapper.select("id");
        List<Permission> childIdList = baseMapper.selectList(wrapper);
        //把childIdList里面的菜单id值获取，封装idList里面，做递归查询
        childIdList.stream().forEach(item->{
            //封装到idList里面
            idlist.add(item.getId());
            //递归查询
            this.selectPermissionChildById(item.getId(),idlist);
        });

    }

    //返回所有菜单list集合进行封装的方法
    public static List<Permission> build(List<Permission> permissionList) {
        //创建list集合，用于数据最终封装
        List<Permission> finalNode = new ArrayList<>();
        //把所有菜单list集合进行遍历，得到顶层菜单pid=0菜单，设置level是1
        for (Permission permissionNode : permissionList) {
            //得到顶层菜单pid=0
            if ("0".equals(permissionNode.getPid())) {
                //设置顶层菜单pid=0菜单
                permissionNode.setLevel(1);
                //根据顶层菜单，向里面进行查询子菜单，封装到finalNode里面
                finalNode.add(selectChildren(permissionNode, permissionList));
            }
        }
        return finalNode;
    }

    private static Permission selectChildren(Permission permissionNode, List<Permission> permissionList) {
        //1.因为向一层菜单里面放二层菜单，二层菜单还要放三层菜单，把对象初始化
        permissionNode.setChildren(new ArrayList<Permission>());

        //2.遍历所有菜单的list的集合，进行判断比较，比较id和pid值是否相同
        for (Permission it : permissionList) {
            //判断pid和id是否相同
            if (permissionNode.getId().equals(it.getPid())) {
                //把父菜单的level值加+1
                int level = permissionNode.getLevel() + 1;
                it.setLevel(level);
                //如果children为空，进行初始化操作
                if (permissionNode.getChildren() == null) {
                    permissionNode.setChildren(new ArrayList<Permission>());
                }
                //把查询出来的子菜单放到父菜单里面
                permissionNode.getChildren().add(selectChildren(it,permissionList));
            }
        }
        return permissionNode;
    }
}
